#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>

#include "../common/logger.h"

/*
Use thread-specific data to write thread-safe versions of dirname() and basename()
*/

#define separator '/'

static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t pathkey;

static void destructor(void *buf)
{
        free(buf);
}

static void create_key(void)
{
        pthread_key_create(&pathkey, destructor);
}

static char *get_mtbuf(void)
{
        pthread_once(&once, create_key);
        char *buf = pthread_getspecific(pathkey);
        if (buf == NULL) {
                buf = malloc(1024);
                pthread_setspecific(pathkey, buf);
        }

        return buf;
}

char *dirname(char *path)
{
        char *path_output = get_mtbuf();
        char *last_separator = strrchr(path, separator);
        snprintf(path_output, last_separator - path + 1, "%s", path);

        return path_output;
}

char *basename(char *path)
{
        char *path_output = get_mtbuf();
        char *last_separator = strrchr(path, separator);
        sprintf(path_output, "%s", last_separator + 1);

        return path_output;
}

void *thread_func(void *arg)
{
        printf("%s\n", dirname("/home/daniel/.bob"));
        printf("%s\n", basename("/home/daniel/.bob"));
}

int main(void)
{
        pthread_t thread_a, thread_b;
        check_system_error(
                pthread_create(&thread_a, NULL, thread_func, NULL),
                "pthread_create");
        check_system_error(
                pthread_create(&thread_b, NULL, thread_func, NULL),
                "pthread_create");
        check_system_error(pthread_join(thread_a, NULL), "pthread_join");
        check_system_error(pthread_join(thread_b, NULL), "pthread_join");

        return EXIT_SUCCESS;
}
